package com.ctrip.cap.client.jenkins;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.ctrip.cap.client.impl.base.BaseClient;
import com.ctrip.cap.client.impl.base.BaseClientImpl.HttpMethodType;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JenkinsRestfulClientImpl extends BaseClient{
	
	public final static String PRETTY = "pretty";
	
	public JenkinsRestfulClientImpl() {
		baseUrl = "http://cimobile.dev.sh.ctripcorp.com:8080";
	}
	
	public JenkinsRestfulClientImpl(String jenkinsServer) {
		baseUrl = jenkinsServer;
	}
	
	public String getAllSlaves() {
		return this.getAllSlaves(false);
	}
	
	public String getAllSlaves(boolean isPretty) {
		return this.baseCall("/computer/api/json", isPretty , HttpMethodType.GET, String.class, PRETTY);
	}
	
	public String getJobInfo(String jobName) {
		return this.getJobInfo(jobName, false);
	}
	
	public String getJobInfo(String jobName, boolean isPretty) {
		return this.baseCall("/job/"+jobName+"/api/json", isPretty , HttpMethodType.GET, String.class, PRETTY);
	}
	
	public String getBuildInfo(String url) {
		return this.getBuildInfo(url, false);
	}
	
	public String getBuildInfo(String url, boolean isPretty) {
		return this.baseCall(url, isPretty , HttpMethodType.GET, String.class, PRETTY);
	}
	
	public String getQueueJob() {
		return this.getQueueJob(false);
	}
	
	public String getQueueJob(boolean isPretty) {
		return this.baseCall("/queue/api/json", isPretty , HttpMethodType.GET, String.class, PRETTY);
	}
	
	public boolean isBuilding(String url) throws JsonProcessingException, IOException {
		ObjectMapper mapper = new ObjectMapper();
		JsonNode root = mapper.readTree(getBuildInfo(url));
		return root.get("building").asBoolean();
	}
	
	public List<String> getBusySlaves() throws JsonProcessingException, IOException{
		List<String> busyMachines = new ArrayList<String>();
		ObjectMapper mapper = new ObjectMapper();
		JsonNode root = mapper.readTree(this.getAllSlaves());
		JsonNode machines = root.get("computer");
		for (JsonNode jsonNode : machines) {
			if(!jsonNode.get("idle").asBoolean())
				busyMachines.add(jsonNode.get("displayName").toString());
		}
		return busyMachines;
	}
	
	public List<String> getBuildList(String jobName) throws JsonProcessingException, IOException {
		List<String> buildUrl = new ArrayList<String>();
		ObjectMapper mapper = new ObjectMapper();
		JsonNode root = mapper.readTree(this.getJobInfo(jobName));
		JsonNode buildList = root.get("builds");
		for (JsonNode jsonNode : buildList) {
			String number = jsonNode.get("number").toString();
			buildUrl.add(String.format("job/%s/%s/api/json", jobName, number));
		}
		return buildUrl;
	}
	
	public List<String> getQueueParams() throws JsonProcessingException, IOException {
		List<String> params = new ArrayList<String>();
		ObjectMapper mapper = new ObjectMapper();
		JsonNode root = mapper.readTree(this.getQueueJob());
		JsonNode items = root.get("items");
		for(JsonNode jsonNode : items) {		
			addParam(params, jsonNode);
		}
		return params;
	}

	public String getJobParams(String url) throws JsonProcessingException, IOException {
		List<String> params = new ArrayList<String>();
		ObjectMapper mapper = new ObjectMapper();
		JsonNode root = mapper.readTree(this.getBuildInfo(url));
		addParam(params, root);
		return params.size() == 0 ? "" : params.get(0);
	}
	
	/**
	 * Default check the latest 15 building
	 * @param jobName
	 * @return
	 * @throws JsonProcessingException
	 * @throws IOException
	 */
	public List<String> getBuildingList(String jobName) throws JsonProcessingException, IOException {
		return this.getBuildingList(jobName, 15);
	}
	
	/**
	 * Maybe Slow
	 * @param jobName
	 * @param num
	 * @return
	 * @throws JsonProcessingException
	 * @throws IOException
	 */
	public List<String> getBuildingList(String jobName, int num) throws JsonProcessingException, IOException {
		List<String> buildingUrl = new ArrayList<String>();
		ObjectMapper mapper = new ObjectMapper();
		JsonNode root = mapper.readTree(this.getJobInfo(jobName));
		JsonNode buildList = root.get("builds");
		int i = 0; 
		for (JsonNode jsonNode : buildList) {
			if(i > num) break;
			String number = jsonNode.get("number").toString();
			String url = String.format("job/%s/%s/api/json", jobName, number);
			if(isBuilding(url)) buildingUrl.add(url);
			i ++;
		}
		return buildingUrl;
	}
	
	private void addParam(List<String> params, JsonNode jsonNode) {
		JsonNode actions = jsonNode.get("actions");
		if(actions == null)
			return;
		JsonNode parameters = null;
		for(JsonNode action : actions) {
			if(action.get("parameters") != null)  {
				parameters = action.get("parameters");
				break;
			}
		}
		if(parameters == null)
			return;
		for(JsonNode parameter : parameters) {
			String name = parameter.get("name").asText();
			if(name.equals("Params") && parameter.get("value") != null) {
				params.add(parameter.get("value").asText());
			}
		}
	}
	
	public static void main(String[] args) {
		JenkinsRestfulClientImpl jImpl = new JenkinsRestfulClientImpl();
		
		try {
			System.out.println(jImpl.getQueueJob());
			System.out.println(jImpl.getJobParams("job/APP.Vacations.TestCase/530/api/json"));
//				s.contains("runid=10606;"));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
